fix(ci): make npm publish idempotent per version - #1047
Open
harijoe wants to merge 3 commits into
Open
Conversation
Contributor
Greptile SummaryThe PR makes npm publication idempotent and serializes runs targeting the same event and commit.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains. Reviews (6): Last reviewed commit: "fix(ci): scope publish concurrency group..." | Re-trigger Greptile |
harijoe
force-pushed
the
fix/publish-idempotent-version
branch
from
August 10, 2026 13:59
b3535e4 to
5aa2d65
Compare
harijoe
force-pushed
the
fix/publish-idempotent-version
branch
from
August 10, 2026 14:17
5aa2d65 to
a72fa29
Compare
Collaborator
Author
|
@greptileai review |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
pnpm publishbehindscripts/publish-if-new.sh, which checksnpm view <name>@<version>and skips instead of failing when that exact version already exists.concurrencygroup keyed on the event name andgithub.shato thepublishjob, so two runs that would publish the same version serialize instead of racing.Context
publish.ymlruns on every branch push and derives the version from the commit SHA (0.0.0-dev.<sha7>/0.0.0-next.<sha7>). Any second publish attempt for a commit already published gets npm's E403 "cannot publish over previously published versions", so the run goes red even though the package is on npm.Concurrency alone only covers the simultaneous case. The same failure happens for non-concurrent attempts: a re-run of a failed job, or a second branch pushed at the same commit. The idempotence guard is what actually fixes those; the concurrency group closes the remaining window where two runs both read the version as unpublished before either writes.
The key includes
github.event_namebecause a release run and a push run at the same commit publish different versions (latestvsnext.<sha>/dev.<sha>), so they must not share a group: a group holds only one pending run, and a queued release run would be displaced by a later push.The group uses
cancel-in-progress: falseso the second run queues rather than killing the first. Cancelling could interrupt a release mid-flight and drop the release-only steps (Mintlify deploy, bump PR, Discord notify), and queuing is harmless now that a duplicate run skips instead of 403ing.The guard is per package rather than per job, so a run that published
skybridgebut died before@skybridge/devtoolscan be re-run and will publish only what is missing.Verification
The branch's own Publish run covers both paths:
skybridge@0.0.0-dev.643ca28and the other two packages normally.skybridge@... is already published, skippingfor all three packages. That re-run is exactly the case that used to fail with E403.Notes
On a
releaseevent, re-publishing an existing tag now logs "already published, skipping" and passes green rather than failing. That is the intended behaviour for job re-runs, but it means a mistakenly re-cut release is no longer loud.It also means a release re-run reaches the release-only steps instead of dying at the publish step. That is the point (you re-run because the Mintlify push or the bump PR failed), and those two are idempotent: the deploy force-pushes the same commit, and the bump PR updates the fixed
chore/bump-versionsbranch. The Discord notification does fire a second time.